package com.github.lh.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.apache.velocity.texen.util.FileUtil;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author <a href="mailto: 393803588@qq.com">刘涵(Hanl)</a>
 * By 2017/12/4
 */
@Slf4j
public class AutoGenerator {

    /**
     * 配置
     */
    private Configuration config;

    public AutoGenerator(Configuration config) {
        log.debug("set config into properties");
        this.config = config;
        log.debug("init velocity");
        initVelocity();
    }

    /**
     * 生成代码
     */
    public void run() {
        log.debug("analyze data");
        this.config.getProperties().values().forEach(this::doGenerate);
        log.debug("finished");
    }

    private void doGenerate(VelocityContext ctx) {
        GlobalConfig gc = this.config.getGlobalConfig();
        TemplateConfig tc = this.config.getTemplateConfig();

        writeInto(tc.getEntity(), (String) ctx.get("entityClassFile"), ctx);

        if (gc.isGenDao()) {
            writeInto(tc.getDao(), (String) ctx.get("daoClassFile"), ctx);
        }
        if (gc.isGenService()) {
            writeInto(tc.getService(), (String) ctx.get("serviceClassFile"), ctx);
            writeInto(tc.getServiceImpl(), (String) ctx.get("serviceImplClassFile"), ctx);
        }
        if (gc.isGenController()) {
            writeInto(tc.getController(), (String) ctx.get("controllerClassFile"), ctx);
        }
    }

    private void initVelocity() {
        Velocity.addProperty("file.resource.loader.class", ClasspathResourceLoader.class.getName());
        Velocity.addProperty(Velocity.FILE_RESOURCE_LOADER_PATH, "");
        Velocity.addProperty(RuntimeConstants.OUTPUT_ENCODING, "utf-8");
        Velocity.addProperty(RuntimeConstants.INPUT_ENCODING, "utf-8");
        Velocity.addProperty("file.resource.loader.unicode", "true");
    }

    private void writeInto(String templateName, String outputPath, VelocityContext ctx) {
        try {
            File file = FileUtil.file(outputPath);
            log.debug("prepare to create file [{}]", outputPath);
            if (!file.exists()) {
                File dir = file.getParentFile();
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                file.createNewFile();
            }
            try (PrintWriter pw = new PrintWriter(file)) {
                Velocity.mergeTemplate(templateName, "utf-8", ctx, pw);
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

}
